package com.expires.test;

import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @program: SpringBootDemos
 * @description:
 * @author: Kangsen
 * @create: 2022-06-09 08:45
 **/

public class CountDownLatchTestCase {
    private static volatile int num = 0;

    static class Worker implements Runnable{

        //工号
        private String workerNo;
        //启动器
        private CountDownLatch startLatch;
        //工作进程中 计数器
        private CountDownLatch workLatch;

        public Worker() {
        }

        public Worker(String workerNo, CountDownLatch startLatch, CountDownLatch workLatch) {
            this.workerNo = workerNo;
            this.startLatch = startLatch;
            this.workLatch = workLatch;
        }

        @Override
        public void run() {
            System.out.println(new Date() + " - " + workerNo + "准备就绪，准备开工了!");
            try {
                startLatch.await();//等待开工指令
                System.out.println(new Date() + " - "+workerNo + " working......");
                TimeUnit.MILLISECONDS.sleep(200);//睡200ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(new Date() + " - "+workerNo + " 工作完成");
                workLatch.countDown();
            }
        }
    }

    static class Writer implements Runnable{
        private CountDownLatch countDownLatch;

        public Writer(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                System.out.println("线程 "+ Thread.currentThread().getName()+"  准备好了 等待执行");
                countDownLatch.countDown();//把门栓放下来了
                while (true){
                    if(num == 1){
                        System.out.println("线程 "+ Thread.currentThread().getName()+"  开始执行");
                        TimeUnit.SECONDS.sleep(2);
                        System.out.println("线程 "+ Thread.currentThread().getName()+"  执行完毕");
                        break;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        /*try {
            int workerCount = 10;
            CountDownLatch startLatch = new CountDownLatch(1);//门栓
            CountDownLatch workLatch = new CountDownLatch(workerCount);//工作线程的计数器
            System.out.println("集合。。。");
            for (int i = 0; i < workerCount; i++) {
                new Thread(new Worker("yyh-"+i,startLatch,workLatch)).start();
            }
            System.out.println("2s 后开始");
            TimeUnit.SECONDS.sleep(2);
            System.out.println("开工");
            startLatch.countDown();//门栓放下来  工作线程开始工作
            workLatch.await();//工作线程计数器 阻塞 等待各个线程的返回
            System.out.println("全部工作完毕  收工");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

        /**
         * 控制一组线程 同一时刻执行
         */
        int threads = 5;
        CountDownLatch countDownLatch = new CountDownLatch(threads);
        for (int i = 0; i < threads; i++) {
            new Thread(new Writer(countDownLatch)).start();
        }
        System.out.println("等待线程做准备");
        try {
            countDownLatch.await();//等待所有的们栓放下来
            //能执行到这里说明所有的门栓都被放下来了
            System.out.println("全部开始执行！");
            num = 1;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
